﻿using MiniFox.Components;
using MiniFox.Scripting.Configurations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace MiniFox.Scripting
{
    /// <summary>
    /// 
    /// </summary>
    [AutoRegister, SpareComponent(typeof(DefaultFunctionContainer))]
    public abstract class FunctionContainer : Component
    {
        /// <summary>
        /// 
        /// </summary>
        protected FunctionContainer()
        {
        }
        /// <summary>
        /// 
        /// </summary>
        [AutoWired]
        protected IScriptingConfigFactory ScriptingConfigFactory
        {
            get; 
            set;
        }
        /// <summary>
        /// 
        /// </summary>
        protected IScriptingConfigProvider Configuration
        {
            get => this.ScriptingConfigFactory.Configuration;
        }
        /// <summary>
        /// 
        /// </summary>
        public FunctionCollection Functions
        {
            get;
            private set;
        } = new FunctionCollection();

        #region 初始化
        /// <summary>
        /// 
        /// </summary>
        [InitInvoke]
        protected virtual void Initialize()
        {
            this.Functions.Clear();
            foreach (IFunctionSetting functionSetting in this.Configuration.Functions)
            {
                var func = CreateFunction(functionSetting);
                foreach (IArgumentSetting argumentSetting in functionSetting.ArgumentSettings)
                {
                    Type argtype = Type.GetType(argumentSetting.Type);
                    func.Arguments.Add(argumentSetting.Name, argtype);
                }
                this.Functions.Add(func);
            }
        }
        #endregion
        /// <summary>
        /// 
        /// </summary>
        /// <param name="functionSetting"></param>
        /// <returns></returns>
        protected virtual FunctionBase CreateFunction(IFunctionSetting functionSetting)
        {
            Type type = Type.GetType(functionSetting.Type);
            object instance = Activator.CreateInstance(type, functionSetting);
            var func = instance as FunctionBase;
            return func;
        }
        #region 获取function实例

        /// <summary>
        /// 
        /// </summary>
        /// <param name="functionName"></param>
        /// <returns></returns>
        public abstract FunctionBase GetFunction(string functionName);
        
        #endregion
        

    }

    internal class DefaultFunctionContainer : FunctionContainer
    {
        public override FunctionBase GetFunction(string functionName)
        {
            return this.Functions[functionName];
        }
    }
}
